using Acme.BookStore.Purchase.Customergoods;
using Acme.BookStore.Purchase.ReceiptOrder;
using Acme.BookStore.PurchaseDto.ReceiptOrderDto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using OfficeOpenXml;
using Microsoft.AspNetCore.Http;
using System.IO;

namespace Acme.BookStore.Purchase.ReceiptOrder
{
    public class ReceiptOrderService : CrudAppService<
        ReceiptOrders,
        ReceiptOrderDto,
        Guid,
        PagedAndSortedResultRequestDto,
        CreateUpdateReceiptOrderDto>,
        IReceiptOrderService
    {
        private readonly IRepository<GoodsModel, Guid> _goodsRepository;

        public ReceiptOrderService(
            IRepository<ReceiptOrders, Guid> repository,
            IRepository<GoodsModel, Guid> goodsRepository)
            : base(repository)
        {
            _goodsRepository = goodsRepository;
        }

        public async Task<ListResultDto<CustomerDropdownDto>> GetCustomerDropdownListAsync()
        {
            var query = await _goodsRepository.GetQueryableAsync();
            
            var customers = await AsyncExecuter.ToListAsync(
                query.Select(x => new CustomerDropdownDto
                {
                    Id = x.Id,
                    ProductName = x.ProductName
                }).Distinct()
            );

            return new ListResultDto<CustomerDropdownDto>(customers);
        }

        public async Task<PagedResultDto<ReceiptOrderDto>> GetListByConditionsAsync(ReceiptOrderQueryDto input)
        {
            var query = await Repository.GetQueryableAsync();

            // 应用筛选条件
            query = query
                .WhereIf(!string.IsNullOrWhiteSpace(input.NoticeNo),
                    x => x.NoticeNo.Contains(input.NoticeNo))
                .WhereIf(!string.IsNullOrWhiteSpace(input.CustomerNode),
                    x => x.CustomerNode.Contains(input.CustomerNode))
                .WhereIf(!string.IsNullOrWhiteSpace(input.Product),
                    x => x.Product.Contains(input.Product))
                .WhereIf(!string.IsNullOrWhiteSpace(input.ProductCode),
                    x => x.ProductCode.Contains(input.ProductCode))
                .WhereIf(!string.IsNullOrWhiteSpace(input.Shipper),
                    x => x.Shipper.Contains(input.Shipper))
                .WhereIf(!string.IsNullOrWhiteSpace(input.Tray),
                    x => x.Tray.Contains(input.Tray))
                .WhereIf(!string.IsNullOrWhiteSpace(input.StorageLocation),
                    x => x.StorageLocation.Contains(input.StorageLocation))
                .WhereIf(input.IsShelved.HasValue,
                    x => x.IsShelved == input.IsShelved);

            // 获取总数
            var totalCount = await AsyncExecuter.CountAsync(query);

            // 排序和分页
            var items = await AsyncExecuter.ToListAsync(
                query.OrderBy(input.Sorting ?? "id")
                    .Skip(input.SkipCount)
                    .Take(input.MaxResultCount)
            );

            // 转换为DTO
            var dtos = ObjectMapper.Map<List<ReceiptOrders>, List<ReceiptOrderDto>>(items);

            return new PagedResultDto<ReceiptOrderDto>(totalCount, dtos);
        }

        public async Task ShelfAsync(Guid id)
        {
            var entity = await Repository.GetAsync(id);
            entity.IsShelved = true;
            await Repository.UpdateAsync(entity);
        }

        public async Task BatchShelfAsync(List<string> ids)
        {
            var guidList = ids.Select(Guid.Parse).ToList();
            var entities = await Repository.GetListAsync(x => guidList.Contains(x.Id));
            foreach (var entity in entities)
            {
                entity.IsShelved = true;
            }
            await Repository.UpdateManyAsync(entities);
        }

        public async Task<byte[]> ExportReceiptOrdersAsync()
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            var items = await Repository.GetListAsync();
            using (var package = new ExcelPackage())
            {
                var worksheet = package.Workbook.Worksheets.Add("ReceiptOrders");
                // 添加表头
                worksheet.Cells[1, 1].Value = "Id";
                worksheet.Cells[1, 2].Value = "NoticeNo";
                worksheet.Cells[1, 3].Value = "CustomerNode";
                worksheet.Cells[1, 4].Value = "Shipper";
                worksheet.Cells[1, 5].Value = "Tray";
                worksheet.Cells[1, 6].Value = "StorageLocation";
                worksheet.Cells[1, 7].Value = "IsShelved";
                worksheet.Cells[1, 8].Value = "Product";
                worksheet.Cells[1, 9].Value = "ProductCode";
                worksheet.Cells[1, 10].Value = "Unit";
                worksheet.Cells[1, 11].Value = "ArrivalQty";
                worksheet.Cells[1, 12].Value = "Qty";
                worksheet.Cells[1, 13].Value = "Volume";
                worksheet.Cells[1, 14].Value = "Weight";
                worksheet.Cells[1, 15].Value = "ProductionDate";
                worksheet.Cells[1, 16].Value = "Batch";
                worksheet.Cells[1, 17].Value = "ReceiptTemperature";
                worksheet.Cells[1, 18].Value = "Remark";
                worksheet.Cells[1, 19].Value = "InWeight";
                worksheet.Cells[1, 20].Value = "OutWeight";
                worksheet.Cells[1, 21].Value = "CreationTime";
                worksheet.Cells[1, 22].Value = "CreatorId";
                worksheet.Cells[1, 23].Value = "LastModificationTime";
                worksheet.Cells[1, 24].Value = "LastModifierId";
                // 添加数据
                for (int i = 0; i < items.Count; i++)
                {
                    var row = i + 2;
                    worksheet.Cells[row, 1].Value = items[i].Id.ToString();
                    worksheet.Cells[row, 2].Value = items[i].NoticeNo;
                    worksheet.Cells[row, 3].Value = items[i].CustomerNode;
                    worksheet.Cells[row, 4].Value = items[i].Shipper;
                    worksheet.Cells[row, 5].Value = items[i].Tray;
                    worksheet.Cells[row, 6].Value = items[i].StorageLocation;
                    worksheet.Cells[row, 7].Value = items[i].IsShelved;
                    worksheet.Cells[row, 8].Value = items[i].Product;
                    worksheet.Cells[row, 9].Value = items[i].ProductCode;
                    worksheet.Cells[row, 10].Value = items[i].Unit;
                    worksheet.Cells[row, 11].Value = items[i].ArrivalQty;
                    worksheet.Cells[row, 12].Value = items[i].Qty;
                    worksheet.Cells[row, 13].Value = items[i].Volume;
                    worksheet.Cells[row, 14].Value = items[i].Weight;
                    worksheet.Cells[row, 15].Value = items[i].ProductionDate;
                    worksheet.Cells[row, 16].Value = items[i].Batch;
                    worksheet.Cells[row, 17].Value = items[i].ReceiptTemperature;
                    worksheet.Cells[row, 18].Value = items[i].Remark;
                    worksheet.Cells[row, 19].Value = items[i].InWeight;
                    worksheet.Cells[row, 20].Value = items[i].OutWeight;
                    worksheet.Cells[row, 21].Value = items[i].CreationTime;
                    worksheet.Cells[row, 22].Value = items[i].CreatorId;
                    worksheet.Cells[row, 23].Value = items[i].LastModificationTime;
                    worksheet.Cells[row, 24].Value = items[i].LastModifierId;
                }
                return package.GetAsByteArray();
            }
        }

        public async Task ImportReceiptOrdersAsync(Stream fileStream)
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            using (var package = new ExcelPackage(fileStream))
            {
                var worksheet = package.Workbook.Worksheets[0];
                int rowCount = worksheet.Dimension.Rows;
                for (int row = 2; row <= rowCount; row++)
                {
                    var noticeNo = worksheet.Cells[row, 2].Text;
                    var customerNode = worksheet.Cells[row, 3].Text;
                    var shipper = worksheet.Cells[row, 4].Text;
                    var tray = worksheet.Cells[row, 5].Text;
                    var storageLocation = worksheet.Cells[row, 6].Text;
                    var isShelved = string.IsNullOrEmpty(worksheet.Cells[row, 7].Text) ? (bool?)null : bool.Parse(worksheet.Cells[row, 7].Text);
                    var product = worksheet.Cells[row, 8].Text;
                    var productCode = worksheet.Cells[row, 9].Text;
                    var unit = worksheet.Cells[row, 10].Text;
                    var arrivalQty = string.IsNullOrEmpty(worksheet.Cells[row, 11].Text) ? (int?)null : int.Parse(worksheet.Cells[row, 11].Text);
                    var qty = string.IsNullOrEmpty(worksheet.Cells[row, 12].Text) ? (int?)null : int.Parse(worksheet.Cells[row, 12].Text);
                    var volume = string.IsNullOrEmpty(worksheet.Cells[row, 13].Text) ? (decimal?)null : decimal.Parse(worksheet.Cells[row, 13].Text);
                    var weight = string.IsNullOrEmpty(worksheet.Cells[row, 14].Text) ? (decimal?)null : decimal.Parse(worksheet.Cells[row, 14].Text);
                    var productionDate = string.IsNullOrEmpty(worksheet.Cells[row, 15].Text) ? (DateTime?)null : DateTime.Parse(worksheet.Cells[row, 15].Text);
                    var batch = worksheet.Cells[row, 16].Text;
                    var receiptTemperature = string.IsNullOrEmpty(worksheet.Cells[row, 17].Text) ? (decimal?)null : decimal.Parse(worksheet.Cells[row, 17].Text);
                    var remark = worksheet.Cells[row, 18].Text;
                    var inWeight = string.IsNullOrEmpty(worksheet.Cells[row, 19].Text) ? (decimal?)null : decimal.Parse(worksheet.Cells[row, 19].Text);
                    var outWeight = string.IsNullOrEmpty(worksheet.Cells[row, 20].Text) ? (decimal?)null : decimal.Parse(worksheet.Cells[row, 20].Text);
                    // 创建实体
                    var entity = new ReceiptOrders(Guid.NewGuid(), noticeNo, customerNode, shipper, tray, storageLocation, isShelved, product, productCode, unit, arrivalQty, qty, volume, weight, productionDate, batch, receiptTemperature, remark, inWeight, outWeight);
                    await Repository.InsertAsync(entity);
                }
            }
        }
    }
} 